#include "Connection.hpp"
class Channel : public Connection
{
public:
    Channel(int fd, callback_t &cb, InetAddr &peer)
    {
        _wflag = true;
        _sockfd = fd;
        SetNonBlock(_sockfd);
        _cb = cb;
        _peer = peer;
    }


    void Read() override
    {
        // 控制读的完整性
        char buffer[1024];
        while (true)
        {
            int n = recv(_sockfd, buffer, sizeof(buffer) - 1, 0); // 非阻塞式读取
            if (n > 0)
            {
                buffer[n] = 0;
                _inbuffer += buffer;
                // std::cout << _inbuffer << std::endl;
            }
            else if (n == 0)
            {
                // 对端关闭
                LOG(LogLevel::INFO) << "client quit:" << _peer.ToString();
                Except();
                return;
            }
            else
            {
                if (errno == EINTR)
                    continue;
                else if (errno == EAGAIN)
                    break;
                else
                {
                    std::cout << n << "haha" << std::endl;
                    LOG(LogLevel::ERROR) << "recv error";
                    Except();
                    break;
                }
            }
        }
    }

    void Write() override
    {
        std::string out;
        
        if (!Package::Unpack(_inbuffer, &out))
        {
            LOG(LogLevel::INFO) << "inbuffer incomplete";
            return;
        }
        // _outbuffer中存有完整的json串
        LOG(LogLevel::INFO) << "inbuffer complete";
        
        _outbuffer = _cb(out);
        if (Package::Pack(_outbuffer))
            LOG(LogLevel::INFO) << "pack success";

        // 开始循环写
        while (true)
        {
            int n = send(_sockfd,&_outbuffer[0], _outbuffer.size(), 0);
            if (n >= 0)
            {
                if (!_wflag)
                {
                    _wflag = true;
                    _owner->EnableReadWrite(_sockfd, true, false);
                }
                // std::cout << _outbuffer << std::endl;
                _outbuffer.erase(0, n);
                if (_outbuffer.size() == 0)
                    break;
            }
            else
            {
                if (errno == EINTR)
                    continue;
                else if (errno == EAGAIN)
                {
                    // 此时缓冲区满了,就需要将EOLLOUT加入检测中
                    if (_wflag)
                    {
                        _wflag = false;
                        _owner->EnableReadWrite(_sockfd,true,true);
                    }
                    break;
                }
                else
                {
                    Except();
                    break;
                }
            }
        }
    }

    void Except() override
    {
        // 出现异常
        _owner->DelConnection(_sockfd);
    }
    ~Channel() override
    {
    }

private:
    InetAddr _peer;
    std::string _inbuffer;
    std::string _outbuffer;
};
